import re
import json
import time

class Node:
    def __init__(self, title, level, path):
        self.id = str(time.time_ns())
        self.title = title
        self.level = level
        self.path = path  # ✅ 新增路径字段
        self.content = [title]
        self.children = []

    def to_dict(self, include_agg=True):
        return {
            "id": self.id,
            "title": self.title,
            "level": self.level,
            "path": self.path,
            "content": self.aggregate_content() if include_agg else self.content,
            "children": [child.to_dict(include_agg=False) for child in self.children]
        }

    def aggregate_content(self):
        merged = list(self.content)
        for child in self.children:
            merged.extend(child.aggregate_content())
        return merged


def parse_md_from_title(md_text):
    lines = md_text.splitlines()
    stack = []  # 每项为 (level, node)
    top_nodes = []
    found_heading = False

    for line in lines:
        match = re.match(r'^(#{1,6})\s+(.*)', line)
        if match:
            found_heading = True
            hashes, title = match.groups()
            level = len(hashes)
            title = title.strip()

            # 计算当前路径
            while stack and stack[-1][0] >= level:
                stack.pop()
            current_path = "/".join(n.title for _, n in stack) + ("/" if stack else "") + title

            node = Node(title, level, current_path)

            if not stack:
                top_nodes.append(node)
            else:
                stack[-1][1].children.append(node)

            stack.append((level, node))
        else:
            stripped_line = line.strip()
            if stripped_line:
                if stack:
                    stack[-1][1].content.append(stripped_line)
                else:
                    # 没有标题时构造一个默认标题
                    fallback_title = "未命名"
                    fallback_node = Node(fallback_title, 1, fallback_title)
                    fallback_node.content.append(stripped_line)
                    top_nodes.append(fallback_node)
                    stack.append((1, fallback_node))

    if not found_heading and not top_nodes and md_text.strip():
        fallback_node = Node("未命名", 1, "未命名")
        for line in lines:
            stripped = line.strip()
            if stripped:
                fallback_node.content.append(stripped)
        top_nodes.append(fallback_node)

    return [node.to_dict() for node in top_nodes]

# 示例使用
if __name__ == "__main__":
    with open("D:\\hbyt\\AI智能投标\\能力组件-附件\\测试1.md", encoding="utf-8") as f:
        md_text = f.read()

    parsed = parse_md_from_title(md_text)
    print(json.dumps(parsed, ensure_ascii=False, indent=2))
